package cn.xinfei.xdecision.engine.runner.service;

import cn.xinfei.xdecision.common.model.component.guiderule.RuleInfo;
import cn.xinfei.xdecision.common.model.component.guiderule.RuleVersion;
import cn.xinfei.xdecision.common.model.component.guiderule.vo.RuleVersionVo;
import cn.xinfei.xdecision.common.model.component.scriptrule.RuleScriptVersion;
import cn.xinfei.xdecision.common.model.enginex.model.EngineNodeModel;
import cn.xinfei.xdecision.common.service.component.guiderule.RuleService;
import cn.xinfei.xdecision.common.service.component.guiderule.RuleVersionService;
import cn.xinfei.xdecision.common.service.component.scriptrule.RuleScriptVersionService;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RuleNodeService {

    @Resource
    private RuleService ruleService;


    @Resource
    private RuleScriptVersionService ruleScriptVersionService;

    @Autowired
    private RuleVersionService versionService;

    public RuleInfo getRuleFromVersionId(String ruleCode, Long versionNo, Long versionId) {
        List<Long> ruleIds = new ArrayList<>();

        RuleInfo ruleInfo = ruleService.queryByCode(ruleCode, versionNo);

//        RuleVersion ruleVersion = versionService.getVersionByVersionNo(ruleCode, versionNo);

        ruleInfo.setVersionId(versionId);

        if (versionId != null && (ruleInfo.getDifficulty() == 2 || ruleInfo.getDifficulty() == 3)) {
            switch (ruleInfo.getDifficulty()) {
                case 2:
                    RuleVersionVo ruleVersionVo = versionService.queryById(versionId);
                    ruleInfo.setVersion(ruleVersionVo);
                    ruleInfo.setVersionNo(ruleVersionVo.getVersionNo());
                    Long rejectBranchId = ruleVersionVo.getRejectBranchId();
                    ruleInfo.setRejectBranchCodeId(rejectBranchId);
                    break;
                case 3:
                    RuleScriptVersion ruleScriptVersion = ruleScriptVersionService.queryById(versionId);
                    ruleInfo.setScriptVersion(ruleScriptVersion);
                    ruleInfo.setVersionNo(ruleScriptVersion.getVersionNo());
                    ruleInfo.setVersion(JSON.parseObject(JSON.toJSONString(ruleScriptVersion), RuleVersionVo.class));
                    Long rejectBranchId1 = ruleScriptVersion.getRejectBranchId();
                    ruleInfo.setRejectBranchCodeId(rejectBranchId1);
                    break;
            }
        }

        return ruleInfo;
    }

    public List<RuleInfo> getRuleFromJsonArray(List<EngineNodeModel> componentList) {
        List<Long> ruleIds = new ArrayList<>();
        Map<Long, Long> map = new HashMap<>();
        List<RuleInfo> ruleInfoResult = new ArrayList<>();
        if (null == componentList || componentList.size() == 0) {
            return ruleInfoResult;
        }
        for (int i = 0; i < componentList.size(); i++) {
            EngineNodeModel ruleObj = componentList.get(i);
            Long versionId = ruleObj.getVersionId();
            Long ruleId = ruleObj.getId();
            if (ruleId != null) {
                ruleIds.add(ruleId);
                if (versionId != null) {
                    map.put(ruleId, versionId);
                }
            }
        }
//        ruleIds= Arrays.asList(384L,376L,374L,390L,382L,396L,386L,380L,378L,392L,394L,388L);
        List<RuleInfo> ruleInfoList = ruleService.getRuleList(ruleIds);
        if (!CollectionUtils.isEmpty(ruleInfoList)) {
            Map<Long, RuleInfo> ruleInfoMap = ruleInfoList.stream()
                    .collect(Collectors.toMap(RuleInfo::getId, v -> v, (p1, p2) -> p1));

            for (int i = 0; i < ruleIds.size(); i++) {
                Long ruleId = ruleIds.get(i);
                RuleInfo ruleInfo = ruleInfoMap.get(ruleId);
                if(ruleInfo!=null) {
                    Long versionId = map.get(ruleInfo.getId());
                    ruleInfo.setVersionId(versionId);
                    ruleInfoResult.add(ruleInfo);
                    if (versionId != null && (ruleInfo.getDifficulty() == 2 || ruleInfo.getDifficulty() == 3)) {
                        switch (ruleInfo.getDifficulty()) {
                            case 2:
                                RuleVersionVo ruleVersionVo = versionService.queryById(versionId);
                                ruleInfo.setVersion(ruleVersionVo);
                                ruleInfo.setVersionNo(ruleVersionVo.getVersionNo());
                                Long rejectBranchId = ruleVersionVo.getRejectBranchId();
                                ruleInfo.setRejectBranchCodeId(rejectBranchId);
                                break;
                            case 3:
                                RuleScriptVersion ruleScriptVersion = ruleScriptVersionService.queryById(versionId);
                                ruleInfo.setScriptVersion(ruleScriptVersion);
                                ruleInfo.setVersionNo(ruleScriptVersion.getVersionNo());
                                ruleInfo.setVersion(JSON.parseObject(JSON.toJSONString(ruleScriptVersion), RuleVersionVo.class));
                                Long rejectBranchId1 = ruleScriptVersion.getRejectBranchId();
                                ruleInfo.setRejectBranchCodeId(rejectBranchId1);
                                break;
                        }
                    }
                }
            }
        }
        return ruleInfoResult;
    }

}
